//
//	HOME AUTOMATION GATEWAY PROJECT
//
//  (c) 2008 mocom software GmbH & Co KG
//	for European Microsoft Innovation Center
//
//  $Author: volker $
//  $Date: 2009-02-26 16:55:56 +0100 (Do, 26. Feb 2009) $
//  $Revision: 276 $
//
//  Microsoft dotNetMF Project
//  Copyright ©2001,2002,2003,2004 Microsoft Corporation
//  One Microsoft Way, Redmond, Washington 98052-6399 U.S.A.
//  All rights reserved.
//  MICROSOFT CONFIDENTIAL
//
//-----------------------------------------------------------------------------
#ifndef _AT91_I2C_H_1
#define _AT91_I2C_H_1 1

typedef struct _AT91S_TWI {
	volatile UINT32	 TWI_CR; 	// Control Register
	volatile UINT32	 TWI_MMR; 	// Master Mode Register
	volatile UINT32	 TWI_SMR; 	// Slave Mode Register
	volatile UINT32	 TWI_IADR; 	// Internal Address Register
	volatile UINT32	 TWI_CWGR; 	// Clock Waveform Generator Register
	volatile UINT32	 Reserved0[3]; 	//
	volatile UINT32	 TWI_SR; 	// Status Register
	volatile UINT32	 TWI_IER; 	// Interrupt Enable Register
	volatile UINT32	 TWI_IDR; 	// Interrupt Disable Register
	volatile UINT32	 TWI_IMR; 	// Interrupt Mask Register
	volatile UINT32	 TWI_RHR; 	// Receive Holding Register
	volatile UINT32	 TWI_THR; 	// Transmit Holding Register
} AT91S_TWI;

// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
#define AT91C_TWI_START       	(0x1 <<  0) // (TWI) Send a START Condition
#define AT91C_TWI_STOP        	(0x1 <<  1) // (TWI) Send a STOP Condition
#define AT91C_TWI_MSEN        	(0x1 <<  2) // (TWI) TWI Master Transfer Enabled
#define AT91C_TWI_MSDIS       	(0x1 <<  3) // (TWI) TWI Master Transfer Disabled
#define AT91C_TWI_SVEN        	(0x1 <<  4) // (TWI) TWI Slave mode Enabled
#define AT91C_TWI_SVDIS       	(0x1 <<  5) // (TWI) TWI Slave mode Disabled
#define AT91C_TWI_SWRST       	(0x1 <<  7) // (TWI) Software Reset
// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
#define AT91C_TWI_IADRSZ      	(0x3 <<  8) // (TWI) Internal Device Address Size
#define AT91C_TWI_IADRSZ_NO     (0x0 <<  8) // (TWI) No internal device address
#define AT91C_TWI_IADRSZ_1_BYTE (0x1 <<  8) // (TWI) One-byte internal device address
#define AT91C_TWI_IADRSZ_2_BYTE (0x2 <<  8) // (TWI) Two-byte internal device address
#define AT91C_TWI_IADRSZ_3_BYTE (0x3 <<  8) // (TWI) Three-byte internal device address
#define AT91C_TWI_MREAD       	(0x1 << 12) // (TWI) Master Read Direction
#define AT91C_TWI_MWRITE		(0x0)
#define AT91C_TWI_DADR        	(0x7F << 16) // (TWI) Device Address
// -------- TWI_SMR : (TWI Offset: 0x8) TWI Slave Mode Register --------
#define AT91C_TWI_SADR        	(0x7F << 16) // (TWI) Slave Address
// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
#define AT91C_TWI_CLDIV       	(0xFF <<  0) // (TWI) Clock Low Divider
#define AT91C_TWI_CHDIV       	(0xFF <<  8) // (TWI) Clock High Divider
#define AT91C_TWI_CKDIV       	(0x7 << 16) // (TWI) Clock Divider
// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
#define AT91C_TWI_TXCOMP		(0x1 <<  0) // (TWI) Transmission Completed
#define AT91C_TWI_RXRDY       	(0x1 <<  1) // (TWI) Receive holding register ReaDY
#define AT91C_TWI_TXRDY		 	(0x1 <<  2) // (TWI) Transmit holding register ReaDY
#define AT91C_TWI_NACK		  	(0x1 <<  8) // (TWI) Not Acknowledged
// -------- TWI_IER/IDR : (TWI Offset: 0x24/28) TWI IER/IDR Register --------
#define AT91C_TWI_INT_ON_NACK	(0x1 << 8)	// enable int on nack
#define AT91C_TWI_INT_ON_COMP	(0x1 << 0)	// enable int on transfer complete
#define AT91C_TWI_INT_ON_RXRDY	(0x1 << 1)	// enable int on rx avail
#define AT91C_TWI_INT_ON_TXRDY	(0x1 << 2)	// enable int on tx empty

struct AT91_I2C_Driver {
		static BOOL Initialize();
		static BOOL Uninitialize();
		static void XActionStart( struct I2C_HAL_XACTION* xAction, bool repeatedStart );		
		static void XActionStop();
		static void GetClockRate( UINT32 rateKhz, UINT8& clockRate, UINT8& clockRate2 );
		static void  GetPins( GPIO_PIN& scl, GPIO_PIN& sda );
	private:
		static UINT32 PopByte(I2C_HAL_XACTION_UNIT* unit, unsigned shift);
		static void PushByte(I2C_HAL_XACTION_UNIT* unit, unsigned val);
		static void ISR( void* arg );
};

#endif // _AT91_I2C_H_1

